package com.mall.goods.service.impl;

import com.mall.cart.model.Cart;
import com.mall.goods.model.AdItems;
import com.mall.goods.model.Sku;
import com.mall.goods.mapper.SkuMapper;
import com.mall.goods.service.IAdItemsService;
import com.mall.goods.service.ISkuService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 商品SKU表 服务实现类
 * </p>
 *
 * @author Darren
 * @since 2022-08-18
 */
@Service
@CacheConfig(cacheNames = "ad-items-skus")
public class SkuServiceImpl extends ServiceImpl<SkuMapper, Sku> implements ISkuService {
    @Autowired
    private IAdItemsService adItemsService;

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public boolean addSku(Sku sku) {
        return super.save(sku);
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public boolean deleteById(String id) {
        return super.removeById(id);
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public boolean updateSku(Sku sku) {
        return super.updateById(sku);
    }

    @Override
    public Sku getById(String id) {
        return super.getById(id);
    }

    @Override
    public List<Sku> selectList(Sku sku) {
        return super.list(getQueryWrapper(sku));
    }

    @Override
    public Page<Sku> selectPage(Page<Sku> page, Sku sku) {
        return super.page(page, getQueryWrapper(sku));
    }

    @Override
    // Cacheable：有缓存使用缓存数据，没有缓存再执行逻辑代码，并将结果缓存
//    @Cacheable(cacheNames = "ad-items-skus", key = "#adItemType")
    @Cacheable(key = "#adItemType")
    public List<Sku> typeSkuItems(Integer adItemType) {
        // 根据type查询所有推广
        List<AdItems> adItems = adItemsService.list(new LambdaQueryWrapper<AdItems>().eq(AdItems::getType, adItemType));
        // 获取所有SkuId
        List<String> skuId = adItems.stream().map(AdItems::getSkuId).collect(Collectors.toList());
        if (skuId.size() == 0)
            return new ArrayList<>();
        return super.listByIds(skuId);
    }

    @Override
    // CacheEvict：删除缓存中的数据
//    @CacheEvict(cacheNames = "ad-items-skus", key = "#adItemType")
    @CacheEvict(key = "#adItemType")
    public void delTypeSkuItems(Integer adItemType) {}

    @Override
    // CachePut：每次都将结果进行缓存
//    @CachePut(cacheNames = "ad-items-skus", key = "#adItemType")
    @CachePut(key = "#adItemType")
    public List<Sku> updateTypeSkuItems(Integer adItemType) {
        // 根据type查询所有推广
        List<AdItems> adItems = adItemsService.list(new LambdaQueryWrapper<AdItems>().eq(AdItems::getType, adItemType));
        // 获取所有SkuId
        List<String> skuId = adItems.stream().map(AdItems::getSkuId).collect(Collectors.toList());
        if (skuId.size() == 0)
            return new ArrayList<>();
        return super.listByIds(skuId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void reduceSkuNum(List<Cart> carts) {
        for (Cart cart : carts) {
            // 语句控制，防止超卖
            int count = this.baseMapper.reduceSkuNum(cart.getSkuId(), cart.getNum());
            if (count <= 0)
                throw new RuntimeException("库存不足!");
        }
    }

    public LambdaQueryWrapper<Sku> getQueryWrapper(Sku sku) {
        return Wrappers.<Sku>lambdaQuery()
                .eq(ObjectUtils.isNotEmpty(sku.getId()), Sku::getId, sku.getId())
                .eq(ObjectUtils.isNotEmpty(sku.getName()), Sku::getName, sku.getName())
                .eq(ObjectUtils.isNotEmpty(sku.getPrice()), Sku::getPrice, sku.getPrice())
                .eq(ObjectUtils.isNotEmpty(sku.getNum()), Sku::getNum, sku.getNum())
                .eq(ObjectUtils.isNotEmpty(sku.getImage()), Sku::getImage, sku.getImage())
                .eq(ObjectUtils.isNotEmpty(sku.getImages()), Sku::getImages, sku.getImages())
                .eq(ObjectUtils.isNotEmpty(sku.getSpuId()), Sku::getSpuId, sku.getSpuId())
                .eq(ObjectUtils.isNotEmpty(sku.getCategoryId()), Sku::getCategoryId, sku.getCategoryId())
                .eq(ObjectUtils.isNotEmpty(sku.getCategoryName()), Sku::getCategoryName, sku.getCategoryName())
                .eq(ObjectUtils.isNotEmpty(sku.getBrandId()), Sku::getBrandId, sku.getBrandId())
                .eq(ObjectUtils.isNotEmpty(sku.getBrandName()), Sku::getBrandName, sku.getBrandName())
                .eq(ObjectUtils.isNotEmpty(sku.getSkuAttribute()), Sku::getSkuAttribute, sku.getSkuAttribute())
                .eq(ObjectUtils.isNotEmpty(sku.getStatus()), Sku::getStatus, sku.getStatus());
    }
}
